/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package chelydra.sharelydra.server.ejb;

import java.util.Collection;
import java.util.Iterator;
import javax.ejb.EJBException;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.LockModeType;
import javax.persistence.NoResultException;

/**
 *
 * @author scallion
 */
@Stateless
public class SLSManagerBean implements SLSManager {

	@PersistenceContext(unitName = "ShareLydraServerPU")
	private EntityManager em;

	public void persist(Object object) {
		em.persist(object);
	}
    
  public SLSUser register(SLSUser user) throws Exception {
		try {
			SLSUser otherUser = this.retrieveUserWithLogin(user.getLogin());
			if (otherUser.getId()>0)
				throw new Exception("Login not available");
		} catch (EJBException ee) {
			//good
		} catch (NoResultException e) {
			//good
		}
		this.persist(user);
		try {
			return this.retrieveUserWithLogin(user.getLogin());
		} catch (EJBException eee) {
			System.err.println("What the hell?!?");
			eee.printStackTrace(System.err);
			throw new Exception("An error occurred. Account not created.");
		}
	}

	public SLSUser connect(SLSUser user, String ip, Integer port) {
		SLSUser u = retrieveUserWithID(user.getId());
		//u.setConnected(true);
		u.setIp(ip);
		u.setPort(port);
		return u;
	}

	public SLSUser disconnect(SLSUser user) {
		SLSUser u = retrieveUserWithID(user.getId());
		//u.setConnected(false);
		u.setIp("");
		return u;
	}

	/**
	 * A user sends a notification to another user in order to become friends
	 * @param from
	 * @param to
	 */
	public void sendFriendshipProposal(SLSUser from, SLSUser to) {
		// TODO: check if the user is already a friend or already denied friendship
		SLSNotification note = new SLSNotification(SLSNotification.FRIENDSHIP_PROPOSAL, "", from, to);
		this.persist(note);
	}

	public SLSUser acceptFriendshipProposal(SLSUser accepting, SLSUser proposing) {
		this.setFriendship(accepting, proposing);
		SLSNotification note = new SLSNotification(SLSNotification.FRIENDSHIP_ACCEPTED, "", accepting, proposing);
		this.em.persist(note);
		return this.retrieveUserWithID(accepting.getId());
	}

	public void declineFriendshipProposal(SLSUser accepting, SLSUser proposing) {
		SLSNotification note = new SLSNotification(SLSNotification.FRIENDSHIP_DECLINED, "", accepting, proposing);
		this.em.persist(note);
	}

	public SLSUser removeFriendship(SLSUser removing, SLSUser removed) {
		SLSUser u1 = retrieveUserWithID(removing.getId());
		SLSUser u2 = retrieveUserWithID(removed.getId());

		u1.getFriends().remove(u2);
		u2.getFriends().remove(u1);

		SLSNotification note = new SLSNotification(SLSNotification.FRIENDSHIP_REMOVED, "", u1, u2);
		this.persist(note);

		return u1;
	}

	public void setFriendship(SLSUser user1, SLSUser user2) {
		SLSUser u1 = retrieveUserWithID(user1.getId());
		SLSUser u2 = retrieveUserWithID(user2.getId());
		u1.getFriends().add(u2);
		u2.getFriends().add(u1);
	}

	public SLSUser retrieveUserWithID(Long id) {
		 SLSUser u = (SLSUser)this.em.createQuery("SELECT u FROM SLSUser u WHERE u.id="+id).getSingleResult();
		 return u;
	}

	public SLSUser retrieveUserWithLogin(String login) {
		SLSUser u = (SLSUser)this.em.createQuery("SELECT u FROM SLSUser u WHERE u.login='"+login+"'").getSingleResult();
		return u;
	}

	public SLSUser retrieveUserWithLoginAndPassword(String login, String password) {
		SLSUser u = (SLSUser)this.em.createQuery("SELECT u FROM SLSUser u WHERE u.login='"+login+"' AND u.password='"+password+"'").getSingleResult();
		return u;
	}

	public Collection<SLSNotification> retrieveNotificationsForUser(SLSUser u) {
		return this.em.createQuery("SELECT n FROM SLSNotification n WHERE n.receiver="+u.getId()).getResultList();
	}

	public void deleteNotificationsForUser(SLSUser u) {
		this.em.createQuery("DELETE FROM SLSNotification n WHERE n.receiver="+u.getId()).executeUpdate();
	}

	public SLSUser modifyProfile (SLSUser user) {
		SLSUser u = retrieveUserWithID(user.getId());
		u.setEmail(user.getEmail());
		u.setFirstName(user.getFirstName());
		u.setLastName(user.getLastName());
		u.setNickname(user.getNickname());
		u.setHideInSearch(user.getHideInSearch());
		u.setHideEmail(user.getHideEmail());

		return u;
	}

	public Collection<SLSUser> searchFriendsForKeywords(Collection<String> keywords) {
		StringBuffer sql = new StringBuffer("SELECT u FROM SLSUser u WHERE u.hideInSearch=0");

		String[] keywordsArray = keywords.toArray(new String[0]);
		if (keywordsArray.length>0) {
			sql.append(" AND ( ");
			for (int i=0; i<keywordsArray.length; i++){
				if (i!=0) sql.append(" OR ");

				sql.append("nickname LIKE '%" + keywordsArray[i] + "%' OR firstName LIKE '%" + keywordsArray[i] + "%' OR lastName LIKE '%" + keywordsArray[i] + "%'");
			}
			sql.append(" )");
		}
		System.err.println(sql.toString());

		return this.em.createQuery(sql.toString()).getResultList();
	}

	public void notifyUsersForFile(SLSUser from, String file, Collection<String> friends) {
		Iterator ite = friends.iterator();
		while (ite.hasNext()) {
			SLSUser user = this.retrieveUserWithLogin((String)ite.next());
			SLSNotification note = new SLSNotification(SLSNotification.NOTIFY_FILE, file, from, user);
			this.persist(note);
		}
	}
}






